package drds.plus.sql_process.abstract_syntax_tree.expression.item.function;

import drds.plus.common.jdbc.Parameters;
import drds.plus.sql_process.abstract_syntax_tree.IExecutePlanVisitor;
import drds.plus.sql_process.abstract_syntax_tree.ObjectCreateFactory;
import drds.plus.sql_process.abstract_syntax_tree.expression.bind_value.BindValue;
import drds.plus.sql_process.abstract_syntax_tree.expression.item.Item;
import lombok.Getter;
import lombok.Setter;

import java.util.ArrayList;
import java.util.List;


public class BooleanFilterImpl extends FunctionImpl<BooleanFilter> implements BooleanFilter {
    @Setter
    @Getter
    protected Operation operation;

    public BooleanFilterImpl() {
        this.argList.add(null);
        this.argList.add(null);
    }

    public String getFunctionName() {
        return operation.getOperationString();
    }


    public void setOperation(Operation operation) {
        if (operation == Operation.and || operation == Operation.or) {
            throw new UnsupportedOperationException(" and or is not support ");
        }
        this.operation = operation;
        this.functionName = operation.getOperationString();

    }

    public Object getColumn() {
        return this.argList.get(0);
    }

    public void setColumn(Object column) {
        this.argList.set(0, column);

    }

    public Object getValue() {

        return this.argList.get(1);
    }

    public List<Object> getValueList() {
        if (this.argList.get(1) instanceof List) {
            return (List) this.argList.get(1);
        } else {
            return null;
        }
    }

    public void setValueList(List valueList) {
        this.argList.set(1, valueList);

    }

    public void setValue(Object value) {
        this.argList.set(1, value);

    }


    public BooleanFilter copy() {
        BooleanFilter booleanFilter = ObjectCreateFactory.createBooleanFilter();
        super.copy(booleanFilter);
        booleanFilter.setOperation(this.getOperation());

        if (this.getValueList() != null) {
            List<Object> valueList = getValueList();
            List<Object> newValueList = new ArrayList(valueList.size());
            for (Object value : valueList) {
                if (value instanceof BindValue) {
                    newValueList.add(((BindValue) value).copy());
                } else if (value instanceof Item) {
                    newValueList.add(((Item) value).copy());
                } else {
                    newValueList.add(value);
                }
            }

            booleanFilter.setValueList(newValueList);
        }

        return booleanFilter;
    }

    public BooleanFilter assignment(Parameters parameters) {
        BooleanFilter booleanFilter = super.assignment(parameters);
        booleanFilter.setOperation(this.getOperation());

        if (booleanFilter.getValueList() != null) {
            List<Object> valueList = getValueList();
            List<Object> newValueList = new ArrayList(valueList.size());
            for (Object value : valueList) {
                if (value instanceof BindValue) {
                    newValueList.add(((BindValue) value).assignment(parameters));
                } else {
                    newValueList.add(value);
                }
            }

            this.setValueList(newValueList);
        } else if (booleanFilter.getValue() != null) {
            Object value = booleanFilter.getValue();
            if (value instanceof BindValue) {
                value = ((BindValue) value).assignment(parameters);
            }

            this.setValue(value);
        }
        return booleanFilter;
    }

    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((operation == null) ? 0 : operation.hashCode());
        return result;
    }

    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }

        if (!(obj instanceof BooleanFilter)) {
            return false;
        }
        BooleanFilter other = (BooleanFilter) obj;
        if (getOperation() != other.getOperation()) {
            return false;
        }
        if (getColumn() == null) {
            if (other.getColumn() != null) {
                return false;
            }
        } else if (!getColumn().equals(other.getColumn())) {
            return false;
        }

        if (getValue() == null) {
            if (other.getValue() != null) {
                return false;
            }
        } else if (!getValue().equals(other.getValue())) {
            return false;
        }

        if (getValueList() == null) {
            return other.getValueList() == null;
        } else
            return getValueList().equals(other.getValueList());

    }

    public String getColumnName() {
        if (this.columnName == null) {
            return null;
        } else {// 在builder阶段，为了保证节点间相互关系，所以可能会对columnName进行重新的定义。
            return columnName;
        }
    }

    public void accept(IExecutePlanVisitor executePlanVisitor) {
        executePlanVisitor.visit(this);
    }
}
